package com.xbongbong.saas.service.impl;/*/*/

import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.pojo.vo.PaasFormDataEsListVO;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.pro.workorder.pojo.vo.WorkOrderOutstockDeleteVO;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.WorkOrderEntity;
import com.xbongbong.saas.domain.entity.WorkOrderProductEntity;
import com.xbongbong.saas.enums.OutstockTypeEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.WorkOrderProductModel;
import com.xbongbong.saas.service.OutstockService;
import com.xbongbong.saas.service.WorkOrderProductService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 *
 * @author 魏荣杰
 * @date 2019/5/9 20:42
 * @since v1.0
 * @version v1.0
 */
@Service("workOrderProductService")
public class WorkOrderProductServiceImpl implements WorkOrderProductService {

    @Resource
    private WorkOrderProductModel workOrderProductModel;
    @Resource
    private OutstockService outstockService;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private EsHelper esHelper;

    @Override
    public List<WorkOrderProductEntity> getSurplusProduct(String corpid, Long workOrderId, WorkOrderEntity workOrderEntity, List<Long> outstockIdList) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("workOrderId", workOrderId);
        param.put("del", DelEnum.NORMAL.getDel());
        List<WorkOrderProductEntity> workOrderProductEntityList = workOrderProductModel.findEntitys(param);

        List<Long> productIdIn = new ArrayList<>();
        for (WorkOrderProductEntity entity : workOrderProductEntityList) {
            productIdIn.add(entity.getProductId());
        }

        PaasFormDataEsListVO paasFormDataEsListVO = outstockService.getOutstockListFromEs(corpid, workOrderId, OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode(), 0);
        List<PaasFormDataEntityExt> paasFormDataESList = paasFormDataEsListVO.getPaasFormDataESList();
        List<Long> outstockIds = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (PaasFormDataEntityExt outstockEsEntity : paasFormDataESList) {
            outstockIds.add(outstockEsEntity.getDataId());
        }

        // 这里去掉特定出库单
        if(outstockIdList != null && !outstockIdList.isEmpty()){
            outstockIds.removeAll(outstockIdList);
        }

        outstockIds.add(-1L);

        param.clear();
        param.put("corpid",corpid);
        param.put("del",0);
        param.put("outstockIdIn",outstockIds);
        // 拿到所有的已出库产品
        List<OutstockProductEntity> outstockProductEntityList = outstockProductModel.findEntitys(param);

        Collection<OutstockProductEntity> mergeOutstockProduct = outstockProductModel.mergeOutstockProduct(outstockProductEntityList);
        outstockProductEntityList.clear();
        outstockProductEntityList.addAll(mergeOutstockProduct);

        Collection<WorkOrderProductEntity> mergeContractProduct = mergeWorkOrderProduct(workOrderProductEntityList);
        workOrderProductEntityList.clear();
        workOrderProductEntityList.addAll(mergeContractProduct);

        Iterator<WorkOrderProductEntity> it = workOrderProductEntityList.iterator();
        while(it.hasNext()) {
            WorkOrderProductEntity workOrderProductEntity = it.next();
            for(OutstockProductEntity outstockProductEntity : outstockProductEntityList){
                if(workOrderProductEntity.getProductId().equals(outstockProductEntity.getProductId())){
                    double num = Arith.sub(workOrderProductEntity.getProductNum(), outstockProductEntity.getProductNum());
                    if(num <= 0.00000001){
                        //如果合同产品数量少于已出库数量，那么就将该产品去掉不显示.（出现这种情况是因为合同重新编辑数量变少了）
                        it.remove();
                        break;
                    }else{
                        workOrderProductEntity.setProductNum(num);
                    }
                }
            }
        }

        return workOrderProductEntityList;
    }

    @Override
    public WorkOrderOutstockDeleteVO getSurplusProductBatch(String corpid, List<Long> workOrderIdList, List<Long> delOutstockIdList) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("workOrderIdIn", workOrderIdList);
        param.put("del", DelEnum.NORMAL.getDel());
        List<WorkOrderProductEntity> workOrderProductList = workOrderProductModel.findEntitys(param);
        List<WorkOrderProductEntity> cloneWorkOrderProductList = (List<WorkOrderProductEntity>) CloneUtil.deepClone(workOrderProductList);

        // 工单和工单产品的对应关系
        Map<Long, List<WorkOrderProductEntity>> workOrderProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (WorkOrderProductEntity workOrderProductEntity : workOrderProductList) {
            Long workOrderId = workOrderProductEntity.getWorkOrderId();
            List<WorkOrderProductEntity> workOrderProductEntities = workOrderProductMap.getOrDefault(workOrderId, new ArrayList<>());
            workOrderProductEntities.add(workOrderProductEntity);
            workOrderProductMap.put(workOrderId, workOrderProductEntities);
        }

        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termQuery("del", 0));
        boolQueryBuilder.filter(termQuery("data." + OutstockEnum.TYPE.getAttr(), OutstockTypeEnum.WORK_ORDER_OUTSTOCK.getCode()));
        boolQueryBuilder.filter(termsQuery("data." + OutstockEnum.REF_ID.getAttr(), workOrderIdList));
        boolQueryBuilder.filter(termsQuery("flowStatus", Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType(), FlowStatusEnum.APPROVAL_PENDING.getType(), FlowStatusEnum.IN_APPROVAL.getType())));
        if (delOutstockIdList != null && !delOutstockIdList.isEmpty()) {
            boolQueryBuilder.mustNot(termsQuery(FieldTypeEnum.DATAID.getAlias(), delOutstockIdList));
        }
        // TODO 这里获取工单关联的除了当前删除的出库单外的剩余其他的出库单，包含了审批中的出库单
        List<PaasFormDataEntityExt> outstockList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_OUTSTOCK,boolQueryBuilder, PaasFormDataEntityExt.class, Arrays.asList(OutstockEnum.getAttrConnectData(OutstockEnum.REF_ID), FieldTypeEnum.DATAID.getAlias()));

        // 工单和工单关联的出库单的对应关系
        Map<Long, List<Long>> workOrderOutstockMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<Long> outstockIds = new ArrayList<>();
        for (PaasFormDataEntityExt outstockEntity : outstockList) {
            outstockIds.add(outstockEntity.getDataId());
            Long workOrderId = outstockEntity.getData().getLong(OutstockEnum.REF_ID.getAttr());
            List<Long> outstockIdList = workOrderOutstockMap.getOrDefault(workOrderId, new ArrayList<>());
            outstockIdList.add(outstockEntity.getDataId());
            workOrderOutstockMap.put(workOrderId, outstockIdList);
        }

        param.clear();
        param.put("corpid", corpid);
        param.put("del", 0);
        param.put("outstockIdIn", outstockIds);
        List<OutstockProductEntity> outstockProductList = outstockProductModel.findEntitys(param);

        // 工单和出库产品的对应关系
        Map<Long, List<OutstockProductEntity>> workOrderOutstockProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (Long workOrderId : workOrderIdList) {
            List<Long> outstockIdList = workOrderOutstockMap.get(workOrderId);
            if (Objects.isNull(outstockIdList)) {
                continue;
            }
            for (OutstockProductEntity outstockProductEntity : outstockProductList) {
                Long outstockId = outstockProductEntity.getOutWarehouseId();
                if (outstockIdList.contains(outstockId)) {
                    List<OutstockProductEntity> outstockProductEntities = workOrderOutstockProductMap.getOrDefault(workOrderId, new ArrayList<>());
                    outstockProductEntities.add(outstockProductEntity);
                    workOrderOutstockProductMap.put(workOrderId, outstockProductEntities);
                }
            }
        }

        // 工单和工单剩余未出库产品的对应关系
        Map<Long, List<WorkOrderProductEntity>> workOrderLeftUnOutstockProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (Long workOrderId : workOrderIdList) {
            List<OutstockProductEntity> outstockProductEntityList = workOrderOutstockProductMap.getOrDefault(workOrderId, new ArrayList<>());
            List<WorkOrderProductEntity> workOrderProductEntityList = workOrderProductMap.getOrDefault(workOrderId, new ArrayList<>());

            Collection<OutstockProductEntity> mergeOutstockProduct = outstockProductModel.mergeOutstockProduct(outstockProductEntityList);
            outstockProductEntityList.clear();
            outstockProductEntityList.addAll(mergeOutstockProduct);

            Collection<WorkOrderProductEntity> mergeContractProduct = mergeWorkOrderProduct(workOrderProductEntityList);
            workOrderProductEntityList.clear();
            workOrderProductEntityList.addAll(mergeContractProduct);

            Iterator<WorkOrderProductEntity> iterator = workOrderProductEntityList.iterator();
            while (iterator.hasNext()) {
                WorkOrderProductEntity workOrderProductEntity = iterator.next();
                for (OutstockProductEntity outstockProductEntity : outstockProductEntityList) {
                    if (workOrderProductEntity.getProductId().equals(outstockProductEntity.getProductId())) {
                        // 计算剩余未出库数量
                        double leftUnOutstockNum = Arith.sub(workOrderProductEntity.getProductNum(), outstockProductEntity.getProductNum());
                        if (leftUnOutstockNum <= 0.00000001) {
                            //如果合同产品数量少于已出库数量，那么就将该产品去掉不显示.（出现这种情况是因为合同重新编辑数量变少了）
                            iterator.remove();
                            break;
                        } else {
                            workOrderProductEntity.setProductNum(leftUnOutstockNum);
                        }
                    }
                }
            }
            workOrderLeftUnOutstockProductMap.put(workOrderId, workOrderProductEntityList);
        }

        WorkOrderOutstockDeleteVO workOrderOutstockDeleteVO = new WorkOrderOutstockDeleteVO();
        workOrderOutstockDeleteVO.setWorkOrderLeftUnOutstockProductMap(workOrderLeftUnOutstockProductMap);
        workOrderOutstockDeleteVO.setWorkOrderProductList(cloneWorkOrderProductList);
        return workOrderOutstockDeleteVO;
    }

    /**
     * Description: 一个工单中的产品可以重复添加，所以需要将合同中id相同的产品数量叠加
     * @param workOrderProductEntityList 工单关联的产品
     * @return java.util.Collection<com.xbongbong.saas.domain.entity.WorkOrderProductEntity>
     * @author 魏荣杰
     * @date 2019/5/9 21:07
     * @since v1.0
     */
    private Collection<WorkOrderProductEntity> mergeWorkOrderProduct(List<WorkOrderProductEntity> workOrderProductEntityList) {
        Map<Long, WorkOrderProductEntity> workOrderProductMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (WorkOrderProductEntity workOrderProduct : workOrderProductEntityList) {
            Long productId = workOrderProduct.getProductId();
            if (workOrderProductMap.containsKey(productId)) {
                WorkOrderProductEntity mergeContractProduct = workOrderProductMap.get(productId);
                Double mergeProductNum = mergeContractProduct.getProductNum();
                Double productNum = workOrderProduct.getProductNum();
                Double mergeNum = Arith.add(mergeProductNum, productNum);
                mergeContractProduct.setProductNum(mergeNum);
                workOrderProductMap.put(productId, mergeContractProduct);
            } else {
                workOrderProductMap.put(productId, workOrderProduct);
            }
        }
        return workOrderProductMap.values();
    }

}
